﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Linq;

namespace IOP.Pulsar.Abstractions
{
    /// <summary>
    /// 生产线服务扩展
    /// </summary>
    public static class ProductLineServicesExtension
    {
        /// <summary>
        /// 添加入口
        /// </summary>
        /// <typeparam name="TEntry"></typeparam>
        /// <typeparam name="TContext"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddProductLineEntry<TEntry, TContext>(this IServiceCollection services)
            where TEntry : class, IProductLineEntry<TContext>
            where TContext : class
        {
            services.AddSingleton<IProductLineBuilder<TContext>, ProductLineBuilder<TContext>>();
            services.AddSingleton<IProductLine<TContext>>((factory) =>
            {
                var startups = factory.GetServices<IStartup>();
                if (startups.Any())
                {
                    var serverBuilder = factory.GetRequiredService<IServerBuilder>();
                    var hostEnv = factory.GetRequiredService<IHostEnvironment>();
                    foreach (var item in startups)
                        item.Configure(serverBuilder, hostEnv);
                }
                var productLineBuilder = factory.GetRequiredService<IProductLineBuilder<TContext>>();
                return new DefaultProductLine<TContext>() { ProductLine = productLineBuilder.Build() };
            });
            services.AddTransient<IProductLineEntry<TContext>, TEntry>();
            return services;
        }

        /// <summary>
        /// 添加入口以及
        /// </summary>
        /// <typeparam name="TEntry"></typeparam>
        /// <typeparam name="TPipelineBuilder"></typeparam>
        /// <typeparam name="TContext"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddProductLineEntryWithCustomBuilder<TEntry, TPipelineBuilder, TContext>(this IServiceCollection services)
            where TEntry : class, IProductLineEntry<TContext>
            where TPipelineBuilder : class, IProductLineBuilder<TContext>
            where TContext : class
        {
            services.AddSingleton<IProductLineBuilder<TContext>, TPipelineBuilder>();
            services.AddSingleton<IProductLine<TContext>>((factory) =>
            {
                var startups = factory.GetServices<IStartup>();
                if (startups.Any())
                {
                    var serverBuilder = factory.GetRequiredService<IServerBuilder>();
                    var hostEnv = factory.GetRequiredService<IHostEnvironment>();
                    foreach (var item in startups)
                        item.Configure(serverBuilder, hostEnv);
                }
                var productLineBuilder = factory.GetRequiredService<IProductLineBuilder<TContext>>();
                return new DefaultProductLine<TContext>() { ProductLine = productLineBuilder.Build() };
            });
            services.AddTransient<IProductLineEntry<TContext>, TEntry>();
            return services;
        }
    }
}
